
/****************************************************************************/
/*Copyright (c) 2011, Florent DEVILLE.                                      */
/*All rights reserved.                                                      */
/*                                                                          */
/*Redistribution and use in source and binary forms, with or without        */
/*modification, are permitted provided that the following conditions        */
/*are met:                                                                  */
/*                                                                          */
/* - Redistributions of source code must retain the above copyright         */
/*notice, this list of conditions and the following disclaimer.             */
/* - Redistributions in binary form must reproduce the above                */
/*copyright notice, this list of conditions and the following               */
/*disclaimer in the documentation and/or other materials provided           */
/*with the distribution.                                                    */
/* - The names of its contributors cannot be used to endorse or promote     */
/*products derived from this software without specific prior written        */
/*permission.                                                               */
/* - The source code cannot be used for commercial purposes without         */ 
/*its contributors' permission.                                             */
/*                                                                          */
/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       */
/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT         */
/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS         */
/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE            */
/*COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,       */
/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,      */
/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;          */
/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER          */
/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT        */
/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN         */
/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE           */
/*POSSIBILITY OF SUCH DAMAGE.                                               */
/****************************************************************************/


#include "mlrMeshLoaderCollada.h"

#include "IPrimitive.h"
#include "CVector3f.h"

#include "dae.h"
#include "1.5/dom/domCOLLADA.h"

//Load a mesh. filename is the complete path+filename of the mesh. Return true if OK or false if an error occurs.
//primitive is a pointer to a primiive interface. It must not be allocated as the function will do it.
bool mlrMeshLoaderCollada::loadMesh(const string& filename, IPrimitive* primitive)const
{
	//open the file
	DAE dae;
	daeElement* root = dae.open(filename);
	if (root == 0)
		return false;

	//get the document
	daeDocument* doc = root->getDocument();

	//get database
	daeDatabase* db = dae.getDatabase();

	//get library geometry node
	daeElement* library_geometries = root->getChild("library_geometries");

	//get all the geometry nodes
	daeTArray<daeSmartRef<daeElement>> geometry = library_geometries->getChildren();

	//for each geometry node
	for(int geoIndex = 0; geoIndex = geometry.getCount(); geoIndex++)
	{
		//get all the mesh node
		daeTArray<daeSmartRef<daeElement>> meshes = geometry[geoIndex]->getChildren();

		//for each mesh
		for(unsigned int meshIndex = 0; meshIndex < meshes.getCount(); meshIndex++)
		{
			//get the mesh node
			daeElement* mesh = meshes[meshIndex];

			//source array
			vector<_vertexBuffer*> sourceArray;

			//get mesh data
			daeTArray<daeSmartRef<daeElement>> meshData = mesh->getChildren();
			for(unsigned int dataID = 0; dataID < meshData.getCount(); dataID++)
			{
				daeElement* currentData = meshData[dataID];

				//source loading
				if(currentData->getElementName() == "source")
				{
					_vertexBuffer* newSource = new _vertexBuffer();
					//loadSource(currentData, newSource);
					//sourceArray.push_back(newSource);
				}

				//triangles loading
				/*else if (currentData->getElement() == "triangles")
				{
					
				}*/
			}
		}
	}

	return false;
}

//load a collada source
bool mlrMeshLoaderCollada::loadSource(daeElement* sourceNode, _vertexBuffer* buffer)
{
	//buffer name
	buffer->_bufferID = sourceNode->getID();

	//get accessor info
	daeTArray<daeSmartRef<daeElement>> sourceData = sourceNode->getChildren();
	daeElement* accessor = sourceData[1]->getChild("accessor");

	string strStride = accessor->getAttribute("stride");
	int stride = atoi(strStride.c_str());

	string strVectorCount = accessor->getAttribute("count");
	int vectorCount = atoi(strVectorCount.c_str());

	int arraySize = stride * vectorCount;

	//get array
	daeElement* dataArray = sourceData[0];
	string strData = dataArray->getCharData();

	vector<string> stringArray;
	stringSplit(strData, stringArray, ' ');

	//create the vector buffer
	buffer->_buffer = new CVector3f[vectorCount];
	buffer->_bufferCount = vectorCount;
	
	//fill the vector buffer
	int vectorID = 0;
	for(int i = 0; i < arraySize; i += stride)
	{
		int id = 0;
		for(int o = i; o < i + stride; o++)
		{
			buffer->_buffer[vectorID].setByID(id, atoi(stringArray[o].c_str()));
			id++;
		}
		
		vectorID++;
	}

	return true;
}

//split a string using a separator
bool mlrMeshLoaderCollada::stringSplit(string& data, vector<string>& split, char sep)
{
	unsigned int cutAt;
	while( (cutAt = data.find_first_of(sep)) != data.npos )
	{
		if(cutAt > 0)
			split.push_back(data.substr(0, cutAt));
		
		data = data.substr(cutAt+1);
	}

	if(data.length() > 0)
		split.push_back(data);
	
	return true;
}

//load a triangles node
bool mlrMeshLoaderCollada::loadTriangles(daeElement* trianglesNode, const vector<_vertexBuffer>& buffers)
{
	string strMaterialName = trianglesNode->getAttribute("material");

	daeTArray<daeSmartRef<daeElement>> triangleData = trianglesNode->getChildren();
	for(int dataID = 0; dataID < triangleData.getCount(); dataID++)
	{

	}

	return false;
}